﻿using BJoin.Application.BObject;
using BJoin.Application.Entity;
using DapperExtensions;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace BJoin.Application.IRepository
{
    public interface IRepository<T> where T : BaseEntity
    {


        /// <summary>
        /// 满足条件的记录数量
        /// </summary>
        /// <param name="database"></param>
        /// <param name="predicate">conditions</param>
        /// <returns></returns>
        Task<long> CountAsync(IDatabase database, object predicate = null);

        /// <summary>
        /// 带参数的查询满足条件的数据
        /// </summary>
        /// <param name="database"></param>
        /// <param name="predicate">conditions</param>
        /// <param name="sort"></param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大条数</param>
        /// <returns></returns>
        Task<IEnumerable<T>> GetListAsync(IDatabase database, int? firstResult, int? maxResults, object predicate = null, String[] sorts = null);

        /// <summary>
        /// 带参数并将结果映射到具有Paging的强类型List
        /// </summary>
        /// <param name="database"></param>
        /// <param name="pageNumber">页码</param>
        /// <param name="rowsPerPage">每页显示数据</param>
        /// <param name="predicate">查询条件</param>
        /// <param name="orderby">排序</param>
        /// <returns></returns>
        Task<Page<T>> GetListPagingAsync(IDatabase database, int pageNumber, int recordsPerPage, object predicate = null, String[] sorts = null);

        /// <summary>
        /// complexsql:根据sql返回集合总数
        /// </summary>
        /// <param name="database"></param>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<long> CountByComplexSqlAsync(IDatabase database, string sql, object param = null);

        /// <summary>
        /// complexsql:根据sql返回对应对象集合
        /// </summary>
        /// <param name="database"></param>
        /// <param name="sql">sql</param>
        /// <returns></returns>
        Task<IEnumerable<TR>> GetListByComplexSqlAsync<TR>(IDatabase database, string sql, object param = null) where TR : class;

        /// <summary>
        /// complexsql:根据sql返回对应分页对象集合
        /// </summary>
        /// <typeparam name="TR"></typeparam>
        /// <param name="database"></param>
        /// <param name="pageNumber">页码</param>
        /// <param name="recordsPerPage">每页显示数据</param>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<Page<TR>> GetListPagingByComplexSqlAsync<TR>(IDatabase database, int pageNumber, int recordsPerPage, string sql, object param = null) where TR : class;


        /// <summary>
        /// 更新一整条数据(支持null)
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity">实体</param>
        /// <param name="predicate">查询条件</param>
        /// <returns></returns>
        Task<bool> UpdateAsync(IDatabase database, T entity, object predicate);

        /// <summary>
        /// 更新部分数据(非Null)
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity">实体</param>
        /// <param name="predicate">conditions</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateSetAsync(IDatabase database, T entity, object predicate);

        /// <summary>
        /// 根据实体删除一条数据
        /// </summary>
        /// <param name="database"></param>
        /// <param name="predicate">conditions</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(IDatabase database, object predicate = null);

        /// <summary>
        /// 并发执行
        /// </summary>
        /// <param name="database"></param>
        /// <param name="sql">sqlscript</param>
        /// <param name="param">param</param>
        /// <returns>返回影响的行数</returns>
        Task<int> ExecuteAsync(IDatabase database, string sql, object param = null);
    }
    public interface IBaseRepository<T>:IRepository<T> where T : BaseEntity
    {
        #region 异步
        /// <summary>
        /// 插入一条记录并返回主键值
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        Task<bool> InsertAsync(IDatabase database, T entity);

        /// <summary>
        /// 插入多条记录
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entities">实体集合</param>
        /// <returns></returns>
        Task<bool> InsertManyAsync(IDatabase database, IEnumerable<T> entities);
        #endregion
    }
    public interface IBaseRepository<T, TKey> : IRepository<T> where T : BaseEntity<TKey>
    {
        #region 异步

        /// <summary>
        /// 通过主键获取实体对象
        /// </summary>
        /// <param name="database"></param>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        Task<T> GetAsync(IDatabase database, TKey id);

        /// <summary>
        /// 插入一条记录并返回主键值
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        Task<TKey> InsertAsync(IDatabase database, T entity);

        /// <summary>
        /// 插入多条记录
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entities">实体集合</param>
        /// <returns></returns>
        Task<IEnumerable<TKey>> InsertManyAsync(IDatabase database, IEnumerable<T> entities);

        /// <summary>
        /// 根据多个Id删除多条数据
        /// </summary>
        /// <param name="database"></param>
        /// <param name="ids">ids</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(IDatabase database, TKey[] id);
        #endregion
    }
    public interface IBaseRepository<T, TKey, TExt> where T : BaseEntity<TKey, TExt> where TExt : BObjExt
    {
        #region 异步

        /// <summary>
        /// 满足条件的记录数量
        /// </summary>
        /// <param name="database"></param>
        /// <param name="predicate">conditions</param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        Task<long> CountAsync(IDatabase database, object predicate = null);

        /// <summary>
        /// 通过主键获取实体对象
        /// </summary>
        /// <param name="database"></param>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        Task<T> GetAsync(IDatabase database, TKey id);

        /// <summary>
        /// 带参数的查询满足条件的数据
        /// </summary>
        /// <param name="database"></param>
        /// <param name="predicate">conditions</param>
        /// <param name="sort"></param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大条数</param>
        /// <returns></returns>
        Task<IEnumerable<T>> GetListAsync(IDatabase database, int? firstResult, int? maxResults, object predicate = null, String[] sorts = null);

        /// <summary>
        /// 带参数并将结果映射到具有Paging的强类型List
        /// </summary>
        /// <param name="database"></param>
        /// <param name="pageNumber">页码</param>
        /// <param name="rowsPerPage">每页显示数据</param>
        /// <param name="predicate">查询条件</param>
        /// <param name="orderby">排序</param>
        /// <returns></returns>
        Task<Page<T>> GetListPagingAsync(IDatabase database, int pageNumber, int recordsPerPage, object predicate = null, String[] sorts = null);

        /// <summary>
        /// complexsql:根据sql返回集合总数
        /// </summary>
        /// <param name="database"></param>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<long> CountByComplexSqlAsync(IDatabase database, string sql, object param = null);

        /// <summary>
        /// complexsql:根据sql返回对应对象集合
        /// </summary>
        /// <param name="database"></param>
        /// <param name="sql">sql</param>
        /// <returns></returns>
        Task<IEnumerable<TR>> GetListByComplexSqlAsync<TR>(IDatabase database, string sql, object param = null) where TR : class;

        /// <summary>
        /// complexsql:根据sql返回对应分页对象集合
        /// </summary>
        /// <typeparam name="TR"></typeparam>
        /// <param name="database"></param>
        /// <param name="pageNumber"></param>
        /// <param name="recordsPerPage"></param>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<Page<TR>> GetListPagingByComplexSqlAsync<TR>(IDatabase database, int pageNumber, int recordsPerPage, string sql, object param = null) where TR : class;

        /// <summary>
        /// 插入一条记录并返回主键值
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<TKey> InsertAsync(IDatabase database, T entity);

        /// <summary>
        /// 插入多条记录
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<IEnumerable<TKey>> InsertManyAsync(IDatabase database, IEnumerable<T> entities);

        /// <summary>
        /// 更新一整条数据(支持null)
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        Task<bool> UpdateAsync(IDatabase database, T entity, object predicate);

        /// <summary>
        /// 更新部分数据(非Null)
        /// </summary>
        /// <param name="database"></param>
        /// <param name="entity">实体</param>
        /// <param name="predicate">conditions</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateSetAsync(IDatabase database, T entity, object predicate);

        /// <summary>
        /// 根据多个Id删除多条数据
        /// </summary>
        /// <param name="database"></param>
        /// <param name="id">id数组</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(IDatabase database, TKey[] id);

        /// <summary>
        /// 根据实体删除一条数据
        /// </summary>
        /// <param name="database"></param>
        /// <param name="predicate">conditions</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(IDatabase database, object predicate = null);

        /// <summary>
        /// 并发执行
        /// </summary>
        /// <param name="database"></param>
        /// <param name="sql">sqlscript</param>
        /// <param name="param">param</param>
        /// <returns>返回影响的行数</returns>
        Task<int> ExecuteAsync(IDatabase database, string sql, object param = null);
        #endregion
    }
}
